package classconverstation.cscl.ist.psu.edu.server;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.openid4java.OpenIDException;
import org.openid4java.consumer.ConsumerException;
import org.openid4java.consumer.ConsumerManager;
import org.openid4java.consumer.VerificationResult;
import org.openid4java.discovery.DiscoveryInformation;
import org.openid4java.discovery.Identifier;
import org.openid4java.message.AuthRequest;
import org.openid4java.message.AuthSuccess;
import org.openid4java.message.ParameterList;
import org.openid4java.message.ax.AxMessage;
import org.openid4java.message.ax.FetchRequest;
import org.openid4java.message.ax.FetchResponse;

import com.google.gwt.core.client.GWT;

import classconverstation.cscl.ist.psu.edu.client.messengers.User;
import classconverstation.cscl.ist.psu.edu.server.authentication.model.OpenIDUserModel;


public class LoginServlet extends javax.servlet.http.HttpServlet {

	final static String YAHOO_ENDPOINT = "https://me.yahoo.com";
	final static String GOOGLE_ENDPOINT = "https://www.google.com/accounts/o8/id";
	final static String USER_OPEN_ID = "user_open_id";
    final static String CC_USER = "cc_user";

	private static final long serialVersionUID = 309579782731258702L;
	private ServletContext context;
	private ConsumerManager manager;

	public void init(ServletConfig config) throws ServletException {
		context = config.getServletContext();
		this.manager = new ConsumerManager();
	}

    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
        
        String op = null;
        
        op = req.getParameter("op");
        
        if (op !=null && op.equalsIgnoreCase("cm")) {
            String psu_id = req.getParameter("u");
            String ac = req.getParameter("ac");
            try {
                if (UserChecker.activateUser(psu_id, ac)) {
                    resp.sendRedirect("../secured/UserActivated.html");
                }
                else {
                    resp.sendRedirect("../secured/UserActivationFailed.html");
                }
                return;
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
        
        if (op !=null && op.equalsIgnoreCase("logout")) {
            req.getSession().invalidate();
            return;
        }
        
        
        OpenIDUserModel user = new OpenIDUserModel();
        Identifier identifier = this.verifyResponse(req, user);
//        // if openid login succeded redirect to home page using our demo account
//        //if your site is open to anyone without login you can do the redirect directly
        if (identifier != null) { // not null means returen returned valid
            
            req.getSession().setAttribute(OpenIDFilter.CURRENT_USER, identifier.getIdentifier());
            req.getSession().setAttribute("user_name", user.getFullName());
            //resp.sendRedirect(req.getParameter("url"));
            // need to check database if we have the user registered
            // code
            
            User cc_user = UserChecker.getUser(user.getEmailAddress());
            req.getSession().setAttribute(LoginServlet.USER_OPEN_ID, user.getEmailAddress());
            req.getSession().setAttribute(LoginServlet.USER_OPEN_ID, user.getEmailAddress());
            System.out.println("In LoginServlet:  ----->" + req.getSession().getAttribute(LoginServlet.USER_OPEN_ID));
            if (cc_user != null) {
                if (UserChecker.isUserActivated(user.getEmailAddress())) {
                    req.getSession().setAttribute(LoginServlet.CC_USER, cc_user);
                    req.getSession().setAttribute(LoginServlet.USER_OPEN_ID, user.getEmailAddress());
                    resp.sendRedirect(req.getParameter("url"));
                }
                else {
                    resp.sendRedirect("../secured/ActivationRequired.html");
                }
            }
            else {
            	resp.sendRedirect("../secured/CCProfile.html");
            }            
            
        } else {
        System.out.println("login with openid failed");
        }
    }
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		String identifier = req.getParameter("identifier");
		this.authRequest(identifier, req, resp);
	}

	// --- placing the authentication request ---
	public String authRequest(String userSuppliedString,
			HttpServletRequest httpReq, HttpServletResponse httpResp) throws IOException
			{
		try {
			// configure the return_to URL where your application will receive
			// the authentication responses from the OpenID provider
			String returnToUrl = httpReq.getRequestURL().toString() + "?" + httpReq.getQueryString();

			// perform discovery on the user-supplied identifier
			List discoveries = manager.discover(userSuppliedString);
			
			// attempt to associate with the OpenID provider
			// and retrieve one service endpoint for authentication
			DiscoveryInformation discovered = manager.associate(discoveries);

			// store the discovery information in the user's session
			httpReq.getSession().setAttribute("openid-disc", discovered);

			// obtain a AuthRequest message to be sent to the OpenID provider
			AuthRequest authReq = manager.authenticate(discovered, returnToUrl);

			FetchRequest fetch = FetchRequest.createFetchRequest();
			if (userSuppliedString.startsWith(GOOGLE_ENDPOINT)) {
				fetch.addAttribute("email",
						"http://axschema.org/contact/email", true);
				fetch.addAttribute("firstName",
						"http://axschema.org/namePerson/first", true);
				fetch.addAttribute("lastName",
						"http://axschema.org/namePerson/last", true);
			} else if (userSuppliedString.startsWith(YAHOO_ENDPOINT)) {
				fetch.addAttribute("email",
						"http://axschema.org/contact/email", true);
				fetch.addAttribute("fullname",
						"http://axschema.org/namePerson", true);
			} else { // works for myOpenID
				fetch.addAttribute("fullname",
						"http://schema.openid.net/namePerson", true);
				fetch.addAttribute("email",
						"http://schema.openid.net/contact/email", true);
			}

			// attach the extension to the authentication request
			authReq.addExtension(fetch);
			httpResp.sendRedirect(authReq.getDestinationUrl(true));
			

		} catch (OpenIDException e) {
		}

		return null;
	}

	// --- processing the authentication response ---
	public Identifier verifyResponse(HttpServletRequest httpReq, OpenIDUserModel user) {
		try {
			// extract the parameters from the authentication response
			// (which comes in as a HTTP request from the OpenID provider)
			ParameterList response = new ParameterList(
					httpReq.getParameterMap());

			// retrieve the previously stored discovery information
			DiscoveryInformation discovered = (DiscoveryInformation) httpReq
					.getSession().getAttribute("openid-disc");

			// extract the receiving URL from the HTTP request
			StringBuffer receivingURL = httpReq.getRequestURL();
			String queryString = httpReq.getQueryString();
			if (queryString != null && queryString.length() > 0)
				receivingURL.append("?").append(httpReq.getQueryString());

			// verify the response; ConsumerManager needs to be the same
			// (static) instance used to place the authentication request
			VerificationResult verification = manager.verify(
					receivingURL.toString(), response, discovered);

			// examine the verification result and extract the verified
			// identifier
			Identifier verified = verification.getVerifiedId();
			if (verified != null) {
				AuthSuccess authSuccess = (AuthSuccess) verification
						.getAuthResponse();
//				user = new OpenIDUserModel();
				if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
					FetchResponse fetchResp = (FetchResponse) authSuccess
							.getExtension(AxMessage.OPENID_NS_AX);

					List emails = fetchResp.getAttributeValues("email");
					String email = (String) emails.get(0);
					List fistnames = fetchResp.getAttributeValues("firstName");
					String fname = (String) fistnames.get(0);
                    List lastnames = fetchResp.getAttributeValues("lastName");
                    String lname = (String) lastnames.get(0);
                    user.setFullName(fname + " " + lname);
                    user.setEmailAddress(email);
				}
				
				return verified; // success
			}
		} catch (OpenIDException e) {
			// present error to the user
		}

		return null;
	}

}